#ifndef __ASPRITE_H__
#define __ASPRITE_H__

#include "PreDefine.h"
#include "System/Graphics.h"
#include "System/Stream.h"

const int END_PAL_IDX = -1;
#define MaxImgNum 25

class CGame ;
typedef char * String ;

class ASprite
{
	friend class Font;

public:
	ASprite();
    static void LoadFile(void* object, CFileStream *pFS);
	void LoadSprite(char* filename);
	~ASprite();
	//ASprite(const int s,const char *file=NULL);
	ASprite(const int s, int palIdx = -1, ...); //palIndex
	ASprite(const char *fname);

	void clear();

    void	Load(char * file, int offset);

    //void	ClearTemporaryBuffer();
    int		GetAFrameTime(int anim, int aframe);
    int		GetAFrames(int anim);
    int		GetFModules(int frame);
    int		GetModuleWidth(int module);
    int		GetModuleHeight(int module);
    int		GetFrameWidth(int frame);
    int		GetFrameHeight(int frame);
    int		GetFrameCollisionLeft(int frame);
    int		GetFrameCollisionTop(int frame);
    int		GetFrameCollisionRight(int frame);
    int		GetFrameCollisionBottom(int frame);
    int		GetFrameModuleX(int frame, int fmodule);
    int		GetFrameModuleY(int frame, int fmodule);
    int		GetFrameModuleWidth(int frame, int fmodule);
    int		GetFrameModuleHeight(int frame, int fmodule);
    int		GetAnimFrame(int anim, int aframe);
    void	GetAFrameRect(int * rc, int anim, int aframe, int posX, int posY, int flags, int hx, int hy);
    void	GetFrameRect(int * rc, int frame, int posX, int posY, int flags, int hx, int hy);
    void	GetFModuleRect(int * rc, int frame, int fmodule, int posX, int posY, int flags, int hx, int hy);
    void	GetModuleRect(int * rc, int module, int posX, int posY, int flags);
    void	SetCurrentAnimation(int anim, bool loop);
    void	SetCurrentAnimation(int animIndex, int anim, bool loop, int startFrame = 0);
    int		GetCurrentAnimation();
    int		GetCurrentAnimation(int animIndex);
    int		GetCurrentAnimationFrame() ;
    int		GetCurrentAnimationFrame(int animIndex) ;
	int		GetAnimationFrameIndex(int animIndex);

	//@brief animation
    //int PaintAndUpdateCurrentAnimation(int posX, int posY, int flags = 0, int hx = 0, int hy = 0);
	int		PlayAnim(int animIndex, int posX, int posY, int flags = 0, int hx = 0, int hy = 0);
	void	StartAnim(int animIndex, bool bLoop = false);
	void	PauseAnim(int animIndex);
	void	ResumeAnim(int animIndex, bool bLoop = false);
	void	StopAnim(int animIndex);
	bool    IsFreeAnim(int animIndex);
    int		PaintAndUpdateCurrentAnimation(int animIndex, float posX, float posY, int flags = 0, int hx = 0, int hy = 0);
	void	UpdateAnimation(int animIndex);
    bool	IsAnimationDone();
	bool	IsAnimationDone2(int animIndex);
    bool	IsAnimationDone(int animIndex);
	void	PaintAniOutIn(int anim, int posX, int posY, T_F32 inScale = 1.0f);

	//@brief frame
    void	PaintAFrame(int anim, int aframe, int posX, int posY, int flags, int hx, int hy);
	void	PaintFrame(int frame, float posX, float posY, int flags = 0, int hx = 0, int hy = 0);
	void	PaintFlashFrame(int frame, int posX, int posY, int flags = 0, int hx = 0, int hy = 0);
	void	PaintBlinkFrame(int frame, int posX, int posY, int flags = 0, int hx = 0, int hy = 0);
	bool	BeginFrmOutIn(int objIdx, T_F32 inScale = 1.0f, int ox = MAGIC_NUM, int oy = MAGIC_NUM);	
	//void	PaintFrmOutIn(int frame, int posX, int posY);
	void	EndFrmOutIn();
	bool	PaintFrmUD(int frame, int posX, int posY);
	void	PaintFrameIn3D(int frame, int posX, int posY, int flags = 0, int hx = 0, int hy = 0);

#ifndef _OptimizePaintFrame
    void	PaintFModule(int frame, int fmodule, int posX, int posY, int flags, int hx, int hy);
#endif
    void	PaintModule(int module, int posX, int posY, int flags = 0);
	void	PaintFlashModule(int module, int posX, int posY, int flags = 0);
	void    PaintFModule(int frame, int index, int posX, int posY, int flags = 0);
	void	BeginBatchFrm(T_F32 x, T_F32 y);
	void	AddFrm(T_S32 frame, T_S32 posX=0, T_S32 posY=0, T_S32 flags=0, T_S32 hx=0, T_S32 hy=0);
	void    AddFModule(T_S32 frame, T_S32 indexf, T_S32 posX, T_S32 posY, T_S32 flags = 0, T_S32 hx=0, T_S32 hy=0);
	//void    AddFModule2(T_S32 frame, T_S32 indexf, T_S32 posX, T_S32 posY, T_S32 flags=0, T_S32 hx=0, T_S32 hy=0);
	void	EndBatchFrm();
	void	PaintModuleIn3D(int module, int posX, int posY);
#ifndef _OptimizePaintFrame
private:
	void	_PaintModule(int module, int posX, int posY, int flags);
#endif
public:
    void	SetCurrentPalette(int pal);
    int		GetCurrentPalette();
	int     GetCurrentTexIndex();
	int*	GenPalette(int type, int * pal, int length); //length == pal.length;
	void	LoadImage(const char* filename);
	int		DrawNumber(int x, int y, int number, int frame_0, int AlignRight = 0, bool percent = false, int gap = 0);

	inline bool	hasLoad(){return _hasLoad;}
private:
	bool		_hasLoad;
    int			_nModules;
#ifdef USE_BS_MODULES_IMG
	T_U08 *		_modules_img_index;
#endif
    short *		_modules_x;
    short *		_modules_y;
    short *		_modules_w;
    short *		_modules_h;
    char *		_frames_nfm;
	int         _nFrames;
    short *	_frames_fm_start;
    char *		_frames_rc;
    char *		_frames_coll;
    T_S08 *		_fmodules;
	int			_nAnims;
    T_S08 *		_anims_naf;
    short *    _anims_af_start;
    T_S08 *		_aframes;
#ifdef USE_MODULE_MAPPINGS
    int **		_map;
	int			_map_length;
#endif
	//u8 * 		_pal;
    //int			_palettes;
	//int	        _crt_pal;
	unsigned int _img[MaxImgNum];
	int			_img_num;
	int	        _crt_img;
    //bool		_alpha;

    //short 		_data_format;
    //int			_i64rle_color_mask;
    //int			_i64rle_color_bits;
    //u8 *		_modules_data; // encoded image data for all modules
	//int			_modules_data_length;
    //int	*		_modules_data_off;	// offset for the image data of each module

    int	*		_current_animation;
    int *		_current_frame;
    int *		_current_frame_time;
    bool *		_is_looping;
	bool		_bNeedFixed;

    CGame *		m_cGame;

private:
	enum {
		ANIM_STOP,
		ANIM_PLAYING,
		ANIM_PAUSED
	};
	int		_cur_map;
	int		_f_ox_if;
	int		_f_oy_if;
	int		_m_x_if;
	int		_m_y_if;
	cGfx*	_gfx;
	int		_animState;	

	int	_DrawObjSelectedCount;
	int		_objSelected;
	char	_frmOutInNum;
	char	_curFrmOutIn;
	T_F32	_curScale;

	short	_pixel_format;
	int		_colors;	// number of colors
	//int		_loadImageData(char* file, int offset);

	void	_ResetInit();
};

#endif
